﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Athena.Runtime.Server.Implementations
{
    using DiscoverAttributes;
    public class ServiceDiscoverByAttribute : IServiceDiscover
    {
        private IServiceEntryFactory _serviceEntryFactory;
        private ILogger _logger;

        public ServiceDiscoverByAttribute(IServiceEntryFactory serviceEntryFactory, ILogger<ServiceDiscoverByAttribute> logger)
        {
            _serviceEntryFactory = serviceEntryFactory;
            _logger = logger;
        }

        public IEnumerable<ServiceEntry> GetEntries<T>(IEnumerable<Type> types, Func<IEnumerable<Type>, IEnumerable<Type>> serviceImplementationTypeFilter = null) where T : Attribute
        {
            return GetEntries(types, typeof(T), serviceImplementationTypeFilter);
        }

        public IEnumerable<ServiceEntry> GetEntries(IEnumerable<Type> types, Type serivceMark = null, Func<IEnumerable<Type>, IEnumerable<Type>> serviceImplementationTypeFilter = null)
        {
            serivceMark = serivceMark ?? typeof(AthenaRpcServiceAttribute);
            var serivces = types.Where(x => x.IsInterface && x.GetCustomAttribute(serivceMark) != null);

            var serviceImplementations = types.Where(x => x.IsClass && !x.IsAbstract && !x.Namespace.StartsWith("System") && !x.Namespace.StartsWith("Microsoft"));

            var entries = new List<ServiceEntry>();

            if (_logger.IsEnabled(LogLevel.Information))
            {
                _logger.LogInformation($"发现了以下服务：{string.Join(",", serivces.Select(x => x.Name))}");
            }

            foreach (var service in serivces)
            {
                foreach (var serviceImplementation in serviceImplementations.Where(x => service.IsAssignableFrom(x)))
                {
                    entries.AddRange(_serviceEntryFactory.CreateServiceEntry(service, serviceImplementation));
                }
            }
            return entries;
        }
    }
}
